﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace JabberBotCore
{
    public class Core
    {
        private readonly List<CoreCommand> commandQueue = new List<CoreCommand>();
        private readonly BackgroundWorker worker = new BackgroundWorker();
        public CoreCommand currentCommand = null;
        JabberProtocol jProt = new JabberProtocol();

        public List<CoreCommand> CommandQueue
        {
            get { return commandQueue; }
        }


        public event JabberProtocol.jProtDel OnMsg;

        private void InvokeOnMsg(JProtEvArgs args)
        {
            JabberProtocol.jProtDel onMsgDel = OnMsg;
            if (onMsgDel != null) onMsgDel(args);
        }

        public Core()
        {
            worker.DoWork += worker_DoWork;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += worker_ProgressChanged;

            jProt.OnMsg += new JabberProtocol.jProtDel(jProt_OnMsg);
            jProt.Connect();
 
        }

        void jProt_OnMsg(JProtEvArgs args)
        {
            if(OnMsg != null) OnMsg(new JProtEvArgs(args.Owner,args.Msg,args.JProt));
        }

        private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            currentCommand = null;
            if (worker.IsBusy) throw new Exception("BUG!!!");
            //if (null != CoreCommandComplete)
            //    CoreCommandComplete(this, new System.EventArgs());
            ProcessCommand(); // Run next command
        }

        private void ProcessCommand()
        {
            if (currentCommand != null || worker.IsBusy || CommandQueue.Count == 0)
            {
                //OnCommandQueueChange();
                if (commandQueue.Count == 0)
                {
                    //if (null != CoreProcessingComplete)
                    //{
                    //    CoreProcessingComplete(this, new System.EventArgs());
                    //    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                    //}
                }
                return;
            }

            //Get command
            currentCommand = CommandQueue[0];
            CommandQueue.RemoveAt(0);

            //OnCommandQueueChange();


            worker.RunWorkerAsync();
            
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            currentCommand.CommandBase.Execute();
        }

        public bool IsBusy
        {
            get
            {
                return
                    currentCommand != null || CommandQueue.Count > 0;
            }
        }

        public void QueueCommand(CoreCommand command)
        {
            if (command != null) commandQueue.Add(command);

            // Process command
            ProcessCommand();
        }
    }
}
